/*
 * Message.h
 *
 *      Author: smirnovaop
 */

#ifndef MESSAGE_H_
#define MESSAGE_H_

#include <string>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <vector>
#include <iostream>
#include "Debug.h"

/**
 * MESSAGE - 				передача данных - текста или просто байтов
 * REGISTRATION - 			запрос о регистрации
 * GET_CLIENTS - 			запрос о зарегистрированных на сервере клиентах
 * RESPONSE_REGISTRATION - 	ответ о регистрации клиента
 * RESPONSE_CLIENTS - 		ответ - все клиенты, зарегистрированные
 * 					  		на сервере
 * EXIT - 					запрос о закрытии соединения с сервером
 */

enum TypeMessage{MESSAGE, REGISTRATION,
				GET_CLIENTS, RESPONSE_REGISTRATION,
				RESPONSE_UNREGISTRATION,
				RESPONSE_CLIENTS, EXIT};

typedef std::vector<u_int32_t> clients;
static const char* TYPE_MESSAGE[EXIT + 1] =
			{
				"MESSAGE",
				"REGISTRATION",
				"GET_CLIENTS",
				"RESPONSE_REGISTRATION",
				"RESPONSE_UNREGISTRATION",
				"RESPONSE_CLIENTS",
				"EXIT"
			};

class Message {
	TypeMessage t_message;
	//message
	u_int32_t 		to;
	u_int32_t 		from;
	u_int32_t		data_len;
	char*	  		data;
	//request
	u_int32_t 		client_id;
	void*			client_ptr;
	clients			clnts;
public:
	Message();
	/**
	 * @len - длина буфера с данными, описывающими сообщение.
	 * @buf - указатель на буфер с данными, описыващими сообщение.
	 */
	Message(int len, char* buf);
	/**
	 * Копирующий конструктор.
	 */
	Message(const Message& msg);

	/**
	 * @return - тип сообщения
	 */
	TypeMessage 	getType() const;
	/**
	 * @return - указатель на буфер с данными сообщения.
	 */
	char*			getData() const;
	/**
	 * @return - длина буфера с данными сообщения.
	 */
	u_int32_t		getDataLen() const;
	/**
	 * @return - id получателя
	 */
	u_int32_t		getTo() const;
	/**
	 *  @return - id отправителя
	 */
	u_int32_t		getFrom() const;
	/**
	 * @return - id клиента, пославшего запрос
	 */
	u_int32_t		getClientId() const;
	/**
	 *  @return - указатель на клиента, пославшего запрос
	 */
	void*			getClientPtr() const;
	/**
	 * @return - std::vector клиентов, зарегистрированных на сервере.
	 */
	clients			getClients() const;
	/**
	 * @return - void. Освобождение всей памяти, занятой данными сообщением.
	 */
	void			clear();
	/**
	 * Заполнение полей стандартного сообщения, передача бинарных данных.
	 * @from 	- id отправителя
	 * @to 		- id получателя
	 * @buf 	- указатель на буфер с данными, необходимыми для передачи.
	 * @buf_len	- длина буфера с данными
	 */
	int				addMessage(u_int32_t from, u_int32_t to, const char* buf = NULL, const size_t buf_len = 0);

	/**
	 * Заполнение полей стандартного сообщения, передача текста.
	 * @from 	- id отправителя
	 * @to 		- id получателя
	 * @msg 	- ссылка на объект класса string из библиотеки STL
	 */
	int				addMessage(u_int32_t from, u_int32_t to, std::string& msg);

	virtual ~Message();
};
	/**
	 * Оператор вывода объекта класса сообщения в стандартный поток вывода.
	 */
	std::ostream& operator <<(std::ostream& os, Message& msg);
	/**
	 * Функции, генерирующие стандартные сообщения -
	 * 		- просто сообщения
	 * 		- запросы серверу о регистрации и разрегистрации,
	 * 		 получении списка зарегистрированных клиентах.
	 * 		- ответы сервера на запросы о регистрации и разрегистрации,
	 * 		получении списка зарегистрированных клиентов.
	 *
	 */
	Message* genMsg(const u_int32_t from, const u_int32_t to, const char* msg);
	Message* genMsg(const u_int32_t from, const u_int32_t to, const char* buf, const size_t buf_len);
	Message* genReqReg(const u_int32_t id, void* client_ptr);
	Message* genExit(const u_int32_t id);
	Message* genReqGetClients(const u_int32_t id);
	Message* genRespReg();
	Message* genRespUnreg();
	Message* genRespClients(clients clnts);


#endif /* MESSAGE_H_ */
